#include <jni.h>
#include <string>
#include <thread>

#include "SLES/OpenSLES.h"
#include "SLES/OpenSLES_Android.h"

#include "config.h"
#include "decoder/AudioDecoder.h"
#include "player/OpenSlPlayer.h"

extern "C" {
#include "libavformat/avformat.h"
}

using namespace std;


// A JNI interface pointer (JNIEnv*) is passed as an argument for each native function mapped to a Java method,
// allowing for interaction with the JNI environment within the native method.
// This JNI interface pointer can be stored, but remains valid only in the current thread.
// Other threads must first call AttachCurrentThread()to attach themselves to the VM and obtain a JNI interface pointer.
// Once attached, a native thread works like a regular Java thread running within a native method.
// The native thread remains attached to the VM until it callsDetachCurrentThread() to detach itself.[3]
// 解释一下：JNIEnv：JNI environment，运行native方法和java方法进行交互。
// 但是这只能在同一个线程中才可以（本地方法栈和栈是同一个线程https://www.cnblogs.com/xiaotian15/p/6945780.html）。
// 如果是c或者c++中新建的线程，那这个线程本身不在java虚拟机中，无法和java互操作。
// 必须首先调用JavaVM对象的AttachCurrentThread()将此线程附加到 VM 并获取 JNI 接口指针。
JavaVM *javaVm = NULL;

//当Android的VM执行到C组件（*so）里的System.loadLibrary()函数时，首先会去执行C组件里的JNI_OnLoad()函数，其用途有二
//一、告诉java VM此C组件使用哪一个JNI版本。如果没有提供JNI_OnLoad()函数，VM会默认使用最老的JNI1.1版本。
//二、可以藉由JNI_OnLoad()来获取jvm。
extern "C"
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
    jint result = -1;
    javaVm = vm; //获取jvm
    JNIEnv *env = NULL;
    if (LOG_DEBUG) LOGD("进入JNI_OnLoad")
    if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4) != JNI_OK) {
        if (LOG_DEBUG) LOGE("初始化JNI_OnLoad失败！")
        return result;
    }
    return JNI_VERSION_1_4;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_tju_ffmpeglib_FFmpegNDK_00024Companion_decode(JNIEnv *env, jobject thiz, jstring url) {
    const char* ch = env->GetStringUTFChars(url, 0);
    string urlStr = string(ch);
    AudioDecoder audioDecoder;
    audioDecoder.decode(urlStr);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_tju_ffmpeglib_FFmpegNDK_00024Companion_playPcm(JNIEnv *env, jobject thiz, jstring url) {
    const char* cUrl = env->GetStringUTFChars(url, 0);
//    OpenSlPlayer op;
    //op.play(cUrl);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_tju_ffmpeglib_FFmpegNDK_00024Companion_pause(JNIEnv *env, jobject thiz) {
    // TODO: implement pause()
}